package ClientDB;
import DataConnectionInterface.*;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class Menu {

	//GUI objects
    private Shell shell;
    private Button newGame;
    private Button quitGame;
    private Image background;
    private Font font;

    //Networking objects
    private ObjectOutputStream out = null;
    private ObjectInputStream in = null;
    private Socket client = null;
    private boolean accessPermitted;

    public static int portNumber;
    
    public Menu(Shell shell) {
        FormLayout layout = new FormLayout();
        this.shell = shell;
        this.background = new Image(shell.getDisplay(), "royal-flush2.jpg");
        this.font = new Font(shell.getDisplay(), "Monotype Corsiva", 14, SWT.ITALIC);
        shell.setBackgroundImage(background);
        shell.setBounds(background.getBounds());
        shell.setText("Fantasy card game");
        shell.setLocation(5, 5);
        shell.setLayout(layout);
        createButtons();
        addButtonListeners();
        addButtonToolTips();
        
    }

    // login with inserted user-name and password
    private void loginButtonLogic(String username, String password, String description, Shell loginShell) {
        
        try{
	    	client = new Socket("localhost", portNumber);
			out = new ObjectOutputStream(client.getOutputStream());
			in = new ObjectInputStream(client.getInputStream());
    	} catch(IOException e){
    		System.exit(0);
    	}
    	
    	try {
    		// send user information
			out.writeObject(new UserInfo(username, password, description));
			// receive permission from server
			accessPermitted = (Boolean) in.readObject();
		} catch (IOException e) {
			System.exit(0);
		} catch (ClassNotFoundException e) {
			System.exit(0);
		}
		
		if(!accessPermitted){
			// close connection
			try {
	    		accessDeniedMB();
				in.close();
				out.close();
		    	client.close();
			} catch (IOException e) {
				
			}
			
			loginShell.close();
			
		} else{
			loginShell.close();
			shell.close();
			
			// proceed to next window
			Display display = Display.getDefault();
	    	shell = new Shell(display, SWT.BORDER);
	        new SelectFantasyUniverseGUI(shell, in, out, client);
	        
	        shell.open();
	        while (!shell.isDisposed()) {
	        	if (!display.readAndDispatch()) {
	        		display.sleep();
	        	}
	        }
		} 	
    }
    
    /** Displays a message box when login is denied
     * 
     */
    public void accessDeniedMB(){
    	MessageBox mb = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
        mb.setMessage("Wrong username or password");
        mb.setText("Access Denied");
        mb.open();
    }

    /** Starts a new login dialog
     * 
     */
    private void newGameButtonLogic() {
    	shell.getDisplay().asyncExec(new Runnable(){

			@Override
			public void run() {
				new LoginDialog();
			}
    		
    	});
        
    }

    /** Quits the game
     * 
     */
    private void quitGameButtonLogic() {
        System.exit(0);
    }

    /** Returns a Form-data for a GUI object
     * 
     */
    private FormData locateButton(int width, int height, int top1, int top2,
            int left1, int left2) {
        FormData result = new FormData(width, height);
        result.top = new FormAttachment(top1, top2);
        result.left = new FormAttachment(left1, left2);
        return result;
    }

    /** Adds listeners to the buttons
     * 
     */
    private void addButtonListeners() {
        newGame.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                newGameButtonLogic();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                
            }
        });
        quitGame.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                quitGameButtonLogic();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                
            }
        });

    }
    /** Adds button tool tips
     * 
     */
    private void addButtonToolTips() {
        newGame.setToolTipText("Begin a new game");
        quitGame.setToolTipText("Are you sure?");
    }

    /** Initializes the Buttons
     * 
     */
    private void createButtons() {
        this.newGame = new Button(shell, SWT.FLAT);
        newGame.setText("New Game");
        newGame.setFont(font);
        FormData newGameFD = locateButton(90, 32, 10, 60,43, 15);
        newGame.setLayoutData(newGameFD);
        this.quitGame = new Button(shell, SWT.FLAT);
        quitGame.setText("Quit");
        quitGame.setFont(font);
        FormData quitGameFD = locateButton(90, 32, 10, 93,43, 15);
        quitGame.setLayoutData(quitGameFD);
    }

    /** Checks if a string contains a non-whitespace character
     * 
     */
    private boolean containsRealTextInput(String in) {
            for(int i = 0; i < in.length(); ++i) {
                char c = in.charAt(i);
                if((' '==c)||('\n'==c)||('\t'==c)) continue;
                else return true;
            }
            return false;
     }

    /** Shows a messagebox with String errString
     * 
     */
    private void showError(Shell shell, String errString) {
        MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
        mb.setMessage(errString);
        mb.setText("Unable to login");
        mb.open();
    }


    /** Login dialog popup class
     *
     */
    private class LoginDialog {

    	//GUI objects
        private Text userNameInput, passwordInput, userDescriptionInput;
        private Label username, password ,userDescription;

        /** A pop-up where the user has to input his:
         *  user-name, password and description, 
         *  all of which may not be empty
         *  
         */
        private LoginDialog() {
        	
            final Display display = shell.getDisplay();
            final Shell shell = new Shell(display);
            shell.setLayout(new GridLayout(2, false));
            shell.setText("Login user");           
            username = new Label(shell, SWT.NULL);
            username.setText("User name:");
            userNameInput = new Text(shell, SWT.SINGLE | SWT.BORDER);
            userNameInput.setText("");
            userNameInput.setTextLimit(30);
            userNameInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            password = new Label(shell, SWT.NULL);
            password.setText("Password");

            passwordInput = new Text(shell, SWT.SINGLE | SWT.BORDER |SWT.PASSWORD);
            passwordInput.setText("");            
            passwordInput.setTextLimit(10);
            passwordInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            userDescription = new Label(shell, SWT.NULL);
            userDescription.setText("Description:");

            userDescriptionInput = new Text(shell, SWT.MULTI | SWT.BORDER );
            userDescriptionInput.setText("");
            
            userDescriptionInput.setTextLimit(1024);
            userDescriptionInput.setLayoutData(new GridData(GridData.FILL_BOTH));

            Button button = new Button(shell, SWT.PUSH);
            button.setText("Login");
            button.setToolTipText("Click to add login");
            button.addSelectionListener(new SelectionListener() {

                public void widgetSelected(SelectionEvent e) {
                    final String name = userNameInput.getText();
                    final String pw = passwordInput.getText();
                    final String descript = userDescriptionInput.getText();
                    if(!name.isEmpty() && !pw.isEmpty() && !descript.isEmpty()) {
                        boolean chkName = containsRealTextInput(name);
                        boolean chkDescription = containsRealTextInput(descript);
                        if( chkName && chkDescription) {   	
                                loginButtonLogic(name, pw, descript, shell);
                        }                        
                        else {
                            if(!chkName)  showError(shell, "Name contains only whitespaces!");                            
                            else showError(shell, "Description contains only whitespaces!");
                        }

                    }
                    else {
                        showError(shell, "Please fillout all the fields");
                    }

                }

                public void widgetDefaultSelected(SelectionEvent e) {

                }
            });

            shell.pack();
            shell.setSize(300, 200);
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }
    }
}